package logger

import (
	"golang.org/x/exp/slog"
	"time"
)

func InitLogger(logPath string, lvStr string, logSize LogSize) {
	pl := &lOutInput{
		RotationTime: 24 * time.Hour,
		RotationSize: logSize,
		LogPath:      logPath,
	}
	lv := GetLevel(lvStr)
	lg := New(LogOptions{
		Level:     lv,
		AddSource: true,
		CtxHandle: nil,
		TextColor: true,
		OutInput: []*LogOutInput{
			&LogOutInput{
				LogType:  LogTypeText,
				OutInput: DefLogOutInput,
			},
			&LogOutInput{
				LogType:  LogTypeJson,
				OutInput: pl,
			},
		},
	})
	SetLogger(lg)
}

func New(opt LogOptions) *LogContainer {
	lb := &LogContainer{
		Opt:     opt,
		jsonLog: nil,
		textLog: nil,
	}
	jsw := NewLogWrite(lb.wJson)
	txw := NewLogWrite(lb.wText)
	lv := &slog.LevelVar{}
	lb.jsonLog = newJsonLog(opt, lv, jsw)
	lb.textLog = newTextLog(opt, lv, txw)
	return lb
}

func newJsonLog(opt LogOptions, lv *slog.LevelVar, lw *LogWrite) FullLogger {
	if len(opt.OutInput) <= 0 {
		return nil
	}
	getJs := func(jo []*LogOutInput) bool {
		for _, v := range jo {
			if v.LogType == LogTypeJson {
				return true
			}
		}
		return false
	}
	if !getJs(opt.OutInput) {
		return nil
	}
	ctxHandle := DefCtxHandle
	if opt.CtxHandle != nil {
		ctxHandle = opt.CtxHandle
	}
	jsonLog := &nLog{
		slog:         newSLog(lw, lv, LogTypeJson, &opt),
		slogLv:       lv,
		ctxHandle:    ctxHandle,
		AddSource:    opt.AddSource,
		SourceOffset: opt.SourceOffset,
		output:       lw,
	}
	jsonLog.SetLevel(opt.Level)
	return jsonLog
}

func newTextLog(opt LogOptions, lv *slog.LevelVar, lw *LogWrite) FullLogger {
	if len(opt.OutInput) <= 0 {
		return nil
	}
	getTx := func(jo []*LogOutInput) bool {
		for _, v := range jo {
			if v.LogType == LogTypeText {
				return true
			}
		}
		return false
	}
	if !getTx(opt.OutInput) {
		return nil
	}
	ctxHandle := DefCtxHandle
	if opt.CtxHandle != nil {
		ctxHandle = opt.CtxHandle
	}
	textLog := &nLog{
		slog:         newSLog(lw, lv, LogTypeText, &opt),
		slogLv:       lv,
		ctxHandle:    ctxHandle,
		AddSource:    opt.AddSource,
		SourceOffset: opt.SourceOffset,
		output:       lw,
	}
	textLog.SetLevel(opt.Level)
	return textLog
}
